package com.example.dl645.protocol.strategy;

import com.example.dl645.model.MeterData;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;

/**
 * DTZY-GF电表解析策略
 */
@Component
public class DtzyGfParseStrategy implements MeterParseStrategy {

    @Override
    public MeterData parse(byte[] dataField) {
        MeterData data = new MeterData();
        try {

            // 1. 总电能：帧30~34 → 内部17~21
            if (dataField.length >= 22) {
                byte[] totalBytes = Arrays.copyOfRange(dataField, 17, 22);
                data.setPositiveTotal(parseBcdToEnergy(totalBytes, "总电能"));
            }

            // 2. 尖费率：帧30~34 → 内部22~26
            if (dataField.length >= 27) {
                byte[] topBytes = Arrays.copyOfRange(dataField, 22, 27);
                data.setPositiveTop(parseBcdToEnergy(topBytes, "尖费率"));
            } else {
                data.setPositiveTop(0.0);
                System.out.println("⚠️ 尖费率字段索引越界，暂设为0");
            }

            // 3. 峰费率：帧35~39 → 内部27~31
            if (dataField.length >= 32) {
                byte[] peakBytes = Arrays.copyOfRange(dataField, 27, 32);
                data.setPositivePeak(parseBcdToEnergy(peakBytes, "峰费率"));
            } else {
                data.setPositivePeak(0.0);
                System.out.println("⚠️ 峰费率字段索引越界，暂设为0");
            }

            // 4. 平费率：帧40~44 → 内部32~36
            if (dataField.length >= 37) {
                byte[] flatBytes = Arrays.copyOfRange(dataField, 32, 37);
                data.setPositiveFlat(parseBcdToEnergy(flatBytes, "平费率"));
            } else {
                data.setPositiveFlat(0.0);
                System.out.println("⚠️ 平费率字段索引越界，暂设为0");
            }

            // 5. 谷费率：帧45~48 → 内部37~41
            if (dataField.length >= 42) {
                byte[] valleyBytes = Arrays.copyOfRange(dataField, 37, 42);
                data.setPositiveValley(parseBcdToEnergy(valleyBytes, "谷费率"));
            } else if (dataField.length >= 38) {
                byte[] valleyBytes = Arrays.copyOfRange(dataField, 37, dataField.length);
                valleyBytes = padTo5Bytes(valleyBytes);
                data.setPositiveValley(parseBcdToEnergy(valleyBytes, "谷费率（补0）"));
            } else {
                data.setPositiveValley(0.0);
                System.out.println("⚠️ 谷费率字段索引越界，暂设为0");
            }

        } catch (Exception e) {
            throw new RuntimeException("DTZY-GF解析失败：" + e.getMessage());
        }
        return data;
    }

    private double parseBcdToEnergy(byte[] bcdLittleBytes, String fieldName) {
        // 1. 小端转大端
        byte[] bcdBigBytes = reverseBytes(bcdLittleBytes);

        // 2. BCD码转十进制字符串
        StringBuilder bcdStr = new StringBuilder();
        for (byte b : bcdBigBytes) {
            int high = (b & 0xF0) >> 4;
            int low = b & 0x0F;
            high = (high > 9) ? 0 : high;
            low = (low > 9) ? 0 : low;
            bcdStr.append(high).append(low);
        }
        String rawBcdStr = bcdStr.toString().trim();

        // 3. 去除前导0
        String noLeadingZeroStr = rawBcdStr.replaceFirst("^0+", "");
        if (noLeadingZeroStr.isEmpty()) {
            return 0.00;
        }

        // 4. 插入小数点（保留2位小数）
        String energyStr;
        if (noLeadingZeroStr.length() <= 2) {
            energyStr = "0." + String.format("%02d", Integer.parseInt(noLeadingZeroStr));
        } else {
            int pointIndex = noLeadingZeroStr.length() - 2;
            energyStr = noLeadingZeroStr.substring(0, pointIndex) + "." + noLeadingZeroStr.substring(pointIndex);
        }
        // 5. 保留4位小数返回
        double energy = Double.parseDouble(energyStr);
        BigDecimal roundedEnergy = new BigDecimal(energy).setScale(4, RoundingMode.HALF_UP);
        System.out.println("✅ " + fieldName + " - 最终值：" + roundedEnergy.doubleValue());
        return roundedEnergy.doubleValue();
    }

    private byte[] padTo5Bytes(byte[] bytes) {
        if (bytes.length >= 5) return bytes;
        byte[] padded = new byte[5];
        System.arraycopy(bytes, 0, padded, 0, bytes.length);
        return padded;
    }


    // 字节倒序
    private byte[] reverseBytes(byte[] bytes) {
        byte[] reversed = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            reversed[i] = bytes[bytes.length - 1 - i];
        }
        return reversed;
    }
    @Override
    public String getMeterModel() {
        return "DTZY-GF";
    }

    @Override
    public byte[] getDataIdentifier() {
        return new byte[]{(byte) 0x44, (byte) 0x54, (byte) 0x5A, (byte) 0x59};
    }
}